package main

import "sync"

func main() {

}

// 单例-饿汉模式
// 就是一定会创建一个对象，不用自己再创建了

type singleton struct {
}

var ins *singleton = &singleton{}

func GetInsOr_eh() *singleton {
	return ins
}

// 这个模式就是包导入的时候初始化的，迫不及待创建了

// 饱汉模式就是需要的时候才创建
// 但是这个模式需要一个问题是非并发安全，正真使用的时候需要加锁
// 下面这个是不安全的模式
func GetInsOr_bh() *singleton {
	if ins == nil {
		ins = &singleton{}
	}
	return ins
} // 如果是并发的时候，如果多个线程访问到这个，会创建多个实例

// 所以使用饱汉模式的并发下需要加锁
var mu sync.Mutex

var ins1 *singleton

func GetInsOr_safe() *singleton {
	if ins1 == nil {
		mu.Lock()
		if ins1 == nil { //锁住之后还是需要再判断一次才对
			ins1 = &singleton{}
		}
		mu.Unlock()
	}
	return ins1
}

// 判断两次那个很麻烦，所以换一个更加优雅的写法
var on sync.Once //保证只会执行一次

func GetInsOr_eligent() *singleton {
	on.Do(func() {
		ins1 = &singleton{}
	})
	return ins1
}
